/*
 * Created by SharpDevelop.
 * User: Jobe
 * Date: 21.10.2006
 * Time: 11:35
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.Collections;
using System.Configuration;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Text.RegularExpressions;
using System.Windows.Forms;

using Microsoft.Win32;
using PlugIn;

 // DevIL support










namespace LauncherPlus
{

	public partial class FormOptions : System.Windows.Forms.Form, IPluginHost
	{
	
		public DirectoryInfo InstallPath = null;
		public System.Resources.ResourceSet Resources = null;
		public PlugIn.AppSettings Settings = null;
		private FormMain Main = null;
		private AppSettingsSection app = null;
		private AppSettingsSection wow = null;
		private ArrayList PluginList = null;
		
		const int ALT = 32;
		const int CTRL = 8;
		const int SHIFT = 4;

		#region form
		
		public FormOptions(FormMain Main)
		{
			try{
	
				InitializeComponent();
	
				this.Main = Main;
				this.Resources = Main.Resources;
				this.Settings = Main.Settings;
				this.app = this.Settings.GetAppSettingsSection("appSettings");
				this.wow = this.Settings.GetAppSettingsSection("wowSettings");
				
				// get game install path
				this.InstallPath = new DirectoryInfo((string)Registry.LocalMachine.OpenSubKey("SOFTWARE\\Blizzard Entertainment\\World of Warcraft").GetValue("InstallPath"));
				
				// load text resources
				LoadResStrings(this,this.Resources);
				
				// get current version
				System.Version Version = Assembly.GetExecutingAssembly().GetName().Version;
				
				// find & start plugins
				if(Main.CommandLine.ContainsKey("PLUGIN")){
					FileInfo PluginFile = new FileInfo((string)Main.CommandLine["PLUGIN"]);
					if(PluginFile.Exists){
						PluginList = new ArrayList();
						PluginList.Clear();
						IPlugin tmpPlugin = Start(PluginFile);
						// if success add to collection
						if((tmpPlugin!=null)&&(tmpPlugin.Registered))PluginList.Add(tmpPlugin);
					}
				}else{
					DirectoryInfo PluginsPath = new DirectoryInfo(Application.StartupPath+"/plugins");
					if(!PluginsPath.Exists)PluginsPath.Create();
					PluginList = new ArrayList();
					PluginList.Clear();
					FileInfo[] PluginFiles = PluginsPath.GetFiles("*.dll");
					foreach( FileInfo PluginFile in PluginFiles ){
						// try to start plugin
						IPlugin tmpPlugin = Start(PluginFile);
						// if success add to collection
						if((tmpPlugin!=null)&&(tmpPlugin.Registered))PluginList.Add(tmpPlugin);
					}
				}

				// load about text
				string AboutText = "";
				AboutText += "{\\rtf1\\ansi\\qc\\f0";
				AboutText += "\\fs64\\par";
				AboutText += "\\fs20Blizzards\\par";
				AboutText += "\\fs20World of Warcraft\\par";
				AboutText += "\\fs18\\par";
				AboutText += "\\fs48LauncherPlus\\par";
				AboutText += "\\fs36 " + Version.Major.ToString() + "." + Version.Minor.ToString() + " \\par";
				AboutText += "\\fs14( build " + Version.Build.ToString() + " )\\par";
				AboutText += "\\fs18\\par";
				AboutText += "\\fs18http://launcherplus.googlecode.com/\\par";
				AboutText += "}";
				this.AboutRichTextBox.Rtf = AboutText;
				
			}catch(Exception ex){
				MessageBox.Show(this, "Failed to initialize options:\n\n" + ex.Message, "System operation failed", MessageBoxButtons.OK, MessageBoxIcon.Stop);
			}
		}
		
		void ButtonOkClick(object sender, System.EventArgs e)
		{

			// set guild URL
			string GuildURL = this.GuildTextBoxURL.Text.Trim().Replace("\\","/");	//transform windows to unix style
			if(GuildURL.Length>0){
				if(!GuildURL.StartsWith("http://"))GuildURL = "http://" + GuildURL;	//prefix missing 'http://'
				if(!GuildURL.EndsWith("/"))GuildURL += "/";	//append missing '/'
			}
			this.Settings.SaveSetting( this.wow, "GuildURL", GuildURL );
				
			// set downloader modus
			SaveDownloaderSettings();
			
			// save language settings
			foreach(cLocale l in Main.Game.Locale){
				if(l.Name.Equals(LanguageComboBox.Items[LanguageComboBox.SelectedIndex])){
					Main.Game.Config.Set("locale",l.Code);
				}
			}
			Main.Game.Config.Save();
			
			this.DialogResult = DialogResult.OK;

		}
		
		void ButtonCancelClick(object sender, System.EventArgs e)
		{
			this.Hide();
		}
				
		void FormOptionsLoad(object sender, System.EventArgs e)
		{
			
			// get guildURL
			GuildTextBoxURL.Text = Settings.LoadSetting( wow, "GuildURL" );

			// get downloader settings
			DownloaderGroupBox.Enabled = LoadDownloaderSettings();
			
			// load layout
			Settings.LoadLayout( app, this );
			
			// load plugins layout
			if(PluginList != null)foreach( IPlugin Plugin in PluginList){
				Plugin.Settings.LoadLayout(Plugin.SettingsSection,Plugin.PluginForm);
			}
			
			// find installed languages
			LanguageComboBox.Items.Clear();
			string code = Main.Game.Config.Get("locale");
			foreach(cLocale l in Main.Game.Locale)if(l.Installed){
				int index = LanguageComboBox.Items.Add(l.Name);
				if(l.Code.Equals(code))LanguageComboBox.SelectedIndex = index;
			}
			
			Main.Game.Config.Load();
			
		}

		void FormOptionsFormClosing(object sender, System.Windows.Forms.FormClosingEventArgs e)
		{
			this.Settings.SaveLayout( this.app, this );
			// save plugins layout
			foreach( IPlugin Plugin in PluginList){
				Plugin.Settings.SaveLayout(Plugin.SettingsSection,Plugin.PluginForm);
			}
		}

		void FormOptionsKeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
		{
			if(e.KeyValue.Equals(112))FormOptionsHelpButtonClicked(sender,new System.ComponentModel.CancelEventArgs());
		}
		
		void FormOptionsHelpButtonClicked(object sender, System.ComponentModel.CancelEventArgs e)
		{
			switch(this.TabControl.SelectedIndex){
				case 0: this.Main.Help(4);	break;	// options
				case 1: this.Main.Help(5);	break;	// addons
				case 2: this.Main.Help(7);	break;	// screenshots
				case 3: this.Main.Help(8);	break;	// roster
				case 4: this.Main.Help(10);	break;	// about->credits
			}
			e.Cancel = true;
		}
		
		/// <summary> Goto account-website to access language-pack download </summary>
		void LanguageButtonClick(object sender, EventArgs e)
		{
			try{
				/* https://www.wow-europe.com/account/ */
				Process.Start("https://www.wow-europe.com/account/");
			} catch (Exception ex) {
				MessageBox.Show("Couldn't load website.\n\n(" + ex.Message + ")");
			}
		}

		/// <summary> Try to load string from resource </summary>
		string LoadResStrings(string Text){
			string ResText = Resources.GetString(Text);
			if(ResText!=null)
				return ResText;
			else
				return Text;
		}

		/// <summary> Try to load strings from resource for object and its children </summary>
		void LoadResStrings(Object Obj, ResourceSet Resources){
			switch(Obj.GetType().Name){
				/* obj with no children or text */
				case "PictureBox":			break;
				case "ProgressBar":			break;
				case "RichTextBox":			break;
				case "ToolStripSeparator":	break;
				case "ListBox":				break;
				case "":				break;
				/* obj has text but no children */
				case "String":					Obj = LoadResStrings((String)Obj);														break;
				case "Label":					((Label)Obj).Text = LoadResStrings(((Label)Obj).Text);									break;
				case "Button":					((Button)Obj).Text = LoadResStrings(((Button)Obj).Text);								break;
				case "TextBox":					((TextBox)Obj).Text = LoadResStrings(((TextBox)Obj).Text);								break;
				case "ColumnHeader":			((ColumnHeader)Obj).Text = LoadResStrings(((ColumnHeader)Obj).Text);					break;
				case "ToolStripStatusLabel":	((ToolStripStatusLabel)Obj).Text = LoadResStrings(((ToolStripStatusLabel)Obj).Text);	break;
				case "ToolStripLabel":			((ToolStripLabel)Obj).Text = LoadResStrings(((ToolStripLabel)Obj).Text);				break;
				case "RadioButton":				((RadioButton)Obj).Text = LoadResStrings(((RadioButton)Obj).Text);						break;
				case "CheckBox":				((CheckBox)Obj).Text = LoadResStrings(((CheckBox)Obj).Text);							break;
				/* obj has text and tooltip */
				case "ToolStripButton":
					((ToolStripButton)Obj).Text = LoadResStrings(((ToolStripButton)Obj).Text);
					((ToolStripButton)Obj).ToolTipText = LoadResStrings(((ToolStripButton)Obj).ToolTipText);
					break;
				/* obj has children but no text */
				case "StatusStrip":			foreach(  Object Child in ((StatusStrip)Obj).Items )LoadResStrings( Child, Resources );			break;
				case "TabControl":			foreach(  Object Child in ((TabControl)Obj).TabPages )LoadResStrings( Child, Resources );		break;
				case "TableLayoutPanel":	foreach(  Object Child in ((TableLayoutPanel)Obj).Controls )LoadResStrings( Child, Resources );	break;
				case "ListView":			foreach(  Object Child in ((ListView)Obj).Columns )LoadResStrings( Child, Resources ); 			break;
				case "ComboBox":			foreach(  Object Child in ((ComboBox)Obj).Items )LoadResStrings( Child, Resources ); 			break;
				case "SplitterPanel":		foreach(  Object Child in ((SplitterPanel)Obj).Controls )LoadResStrings( Child, Resources );	break;
				case "Panel":				foreach(  Object Child in ((Panel)Obj).Controls )LoadResStrings( Child, Resources );			break;
				case "ToolStrip":			foreach(  Object Child in ((ToolStrip)Obj).Items )LoadResStrings( Child, Resources );			break;
				case "ToolStripComboBox":	foreach(  Object Child in ((ToolStripComboBox)Obj).Items )LoadResStrings( Child, Resources );	break;
				case "SplitContainer":
					LoadResStrings( ((SplitContainer)Obj).Panel1, Resources );
					LoadResStrings( ((SplitContainer)Obj).Panel2, Resources );
					break;
				/* obj has children and text */
				case "FormOptions":
					((FormOptions)Obj).Text = LoadResStrings(((FormOptions)Obj).Text);
					foreach(  Object Child in ((FormOptions)Obj).Controls )LoadResStrings( Child, Resources );
					break;
				case "TabPage":
					((TabPage)Obj).Text = LoadResStrings(((TabPage)Obj).Text);
					foreach(  Object Child in ((TabPage)Obj).Controls )LoadResStrings( Child, Resources );
					break;
				case "GroupBox":
					((GroupBox)Obj).Text = LoadResStrings(((GroupBox)Obj).Text);
					foreach(  Object Child in ((GroupBox)Obj).Controls )LoadResStrings( Child, Resources );
					break;
				/* unknown obj */
				default:
				Debug.Print(Obj.GetType().Name+"\n");
			        break;			
			}
		}
		
		/// <summary>Load blizzards downloader settings from registry</summary>
		/// <returns>true on success</returns>
		bool LoadDownloaderSettings(){
			try{
				int status = DownloaderStatus;
				// set checkboxes from downloadstatus
				DownloaderCheckBoxWhilePlay.Checked	= ((status&1)==1);
				DownloaderCheckBoxAfterExit.Checked	= ((status&2)==2);
				DownloaderCheckBoxThrottle.Checked	= ((status&4)==4);
				return true;
			}catch(Exception ex){
				Debug.Print("LoadDownloaderSettings: " + ex.ToString());
				return false;
			}
		}
		
		void SaveDownloaderSettings(){
				// convert checkbox settings to downloadstatus
				int status = 0;
				if(DownloaderCheckBoxWhilePlay.Checked)status+=2;
				if(DownloaderCheckBoxAfterExit.Checked)status+=1;
				if(DownloaderCheckBoxThrottle.Checked)status+=4;
				DownloaderStatus = status;
		}
		
		/// <summary>
		/// Get/Set Downloader Status ( 0 - 7 ):
		/// Bit 1 = Download while playing
		/// Bit 2 = Download after exit
		/// Bit 3 = Full speed download
		/// </summary>
		private int DownloaderStatus
		{
			get{
				RegistryKey rkDownloader = Microsoft.Win32.Registry.CurrentUser;
				rkDownloader = rkDownloader.OpenSubKey("Software");
				rkDownloader = rkDownloader.OpenSubKey("Blizzard Entertainment");
				rkDownloader = rkDownloader.OpenSubKey("Blizzard Downloader");
				// convert registry settings to downloadstatus(0-3)
				int BackgroundDownloadMode = (int)rkDownloader.GetValue("Background Download Mode");
				int DisableBackgroundDownload = (int)rkDownloader.GetValue("Disable Background Download");
				int FullSpeedBackgroundDownload = (int)rkDownloader.GetValue("Full Speed Background Download");
				if(BackgroundDownloadMode<1)BackgroundDownloadMode=3;
				int status = (BackgroundDownloadMode*(1-DisableBackgroundDownload)+(FullSpeedBackgroundDownload*4));
				return status;
			}
			set{
				RegistryKey rkDownloader = Microsoft.Win32.Registry.CurrentUser;
				rkDownloader = rkDownloader.OpenSubKey("Software");
				rkDownloader = rkDownloader.OpenSubKey("Blizzard Entertainment");
				rkDownloader = rkDownloader.OpenSubKey("Blizzard Downloader",true);
				// convert downloadstatus ( 0 - 7 ) to blizzard registry settings
				value = ( value % 8 );
				rkDownloader.SetValue("Background Download Mode",((3-(value%4))%3));
				rkDownloader.SetValue("Disable Background Download",((3-(value%4))/3));
				rkDownloader.SetValue("Full Speed Background Download",(value/4));
			}
		}
		
		#endregion function
		
		#region Plugin
		/// <summary>
		/// Load and create the specific plugin object
		/// </summary>
		/// <param name="args">Plugin name</param>
		public IPlugin Start(FileInfo PluginFile)
		{
			Type ObjType = null;
			IPlugin Plugin = null;
			// load the dll
			try{
				// load it
				Assembly ass = null;
				ass = Assembly.LoadFile(PluginFile.FullName);
				if (ass != null){
					ObjType = ass.GetType(Path.GetFileNameWithoutExtension(PluginFile.Name)+".PlugIn");
					Debug.Print("Plugin '"+PluginFile.Name+"' found.\n");
				}else{
					Debug.Print("Plugin '"+PluginFile.Name+"' is no valid plugin.\n");
				}
			}catch (Exception ex){
				Debug.Print(ex.Source+":"+ex.Message);
			}
			try{
				// OK Lets create the object as we have the Report Type
				if (ObjType != null){
					Plugin = (IPlugin)Activator.CreateInstance(ObjType);
					// set plugins source dll-file
					Plugin.FileName = PluginFile.FullName;
					// register with this host
					Plugin.Host = this;
					Debug.Print("Plugin '"+PluginFile.Name+"' loaded.\n");
				}else{
					Debug.Print("Plugin '"+PluginFile.Name+"' not loaded!\n");
				}
			}catch (Exception ex){
				Debug.Print("FormOptions.Start: " + ex.ToString());
			}
			return Plugin;
		}
		
		/// <summary>
		/// Register plugin with app and create its personal tabpage.
		/// </summary>
		/// <param name="PluginList">Plugin to register</param>
		/// <returns>True on success</returns>
		public bool Register(IPlugin Plugin)
		{
			try{
				// create tab page
				Plugin.PluginForm.Dock = DockStyle.None;
				Plugin.PluginForm.MinimumSize = new Size(735,340);
				Plugin.PluginForm.MaximumSize = new Size(735,340);
				Plugin.PluginForm.SetBounds(0,0,735,340);
				TabPage tp = new TabPage(Plugin.Name);
				tp.Controls.Add(Plugin.PluginForm);
				// add to options form
				TabControl.Controls.Add(tp);
				TabControl.Controls.SetChildIndex(tp,0);
				// create own settings section
				string pluginFilename = Plugin.FileName;
				string SectionName = Path.GetFileNameWithoutExtension(pluginFilename);
				Regex.Replace(SectionName,"[^a-zA-Z0-9]","");
				SectionName += "Settings";
				Plugin.Settings = this.Settings;
				Plugin.SettingsSection = Settings.GetAppSettingsSection(SectionName);
				return true;
			}catch(Exception ex){
				Debug.Print("FormOptions.Register: "+ex.ToString());
				return false;
			}
		}
		
		/// <summary>
		/// Get path to wow installation.
		/// </summary>
		/// <returns>Path to wow</returns>
		public DirectoryInfo GetInstallPath(){
			return InstallPath;
		}
		
		/// <summary>
		/// Get global settings container.
		/// </summary>
		/// <returns>Global settings container</returns>
		public PlugIn.AppSettings GetSettings(){
			return Settings;
		}
		
		#endregion
		
		void TestToolStripButtonClick(object sender, EventArgs e)
		{
			
		}
	}
}
